﻿
using System;

namespace LxCFD
{
    public class WallDistance : ScalarHeadBase
    {
        public double[] x;
        public bool[] isWallAdj;
        protected bool[] isWall;
        private FvZone meshZone;
        public override void CheckCreate(FvZone zone)
        {
            base.CheckCreate(zone);
            meshZone = zone as FvZone;
            if (isWall == null || isWall.Length != zone.GetThreadCount())// BoundThreads.Count)
            {
                isWall = new bool[zone.GetThreadCount()];//.BoundThreads.Count];
                IsInitialized = false;
            }
            LxTool.CheckCreateArray(ref x, InnerIndex.CellIDs.GetCount());
            LxTool.CheckCreateArray(ref isWallAdj, InnerIndex.CellIDs.GetCount());
        }
        public void SetBound_Wall(int ThreadIndexInZone)
        {
            if (isWall[ThreadIndexInZone])
            {
            }
            else
            {//原来不是wall
                isWall[ThreadIndexInZone] = true;
                IsInitialized = false;
            }
        }
        public void SetBound_NotWall(int ThreadIndexInZone)
        {
            if (isWall[ThreadIndexInZone])
            {
                isWall[ThreadIndexInZone] = false;
                IsInitialized = false;
            }
        }
        public PossionEquation MakePDECalulator()
        {
            PossionEquation walldis = new PossionEquation();
            walldis.CheckCreate(Zone);
            walldis.SetZone_CommonTerm(new Value1Const.Double(1), new Value1Const.Double(1), new Value1Const.Double(0), 1);
            int i1 = 0;
            foreach (var t in meshZone.BoundThreads)
            {
                if (isWall[i1])
                {
                    walldis.SetBoundary_FixValue(new Value1Const.Double(0), t);
                }
                else
                {
                    walldis.SetBoundary_FixFlux(new Value1Const.Double(0), t);
                }
                i1++;
            }
            return walldis;

        }
        public void CalDistanceFromPDE(EquationBase PDE, int taskIndex)
        {
            {
                double mindis = meshZone.PhysicalModel.MinWallDistanceLimit;
                double[] PDEx = PDE.x;
                Vector3d[] gradx = PDE.Grad;
                Zone.InnerIndex.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
                for (; i1 < endp1; i1++)
                {
                    double square = gradx[i1].CalLengthSquared();
                    double d = Math.Sqrt(square + 2 * PDEx[i1]) - Math.Sqrt(square);
                    x[i1] = Math.Max(d, mindis);
                    isWallAdj[i1] = false;
                }
//#if DEBUG
//                for (i1 = InnerIndex.FaceIDs.End + 1; i1 <= TotalIndex.FaceIDs.End; i1++)
//                {
//                    ref Face face = ref faces[i1];
//                    x[face.NSideCell] = x[face.OSideCell];
//                }
//#endif
            }
            MultiThreads.Sync(taskIndex);
            {
                for (int i2 = 0; i2 < meshZone.BoundThreads.Count; i2++)
                {
                    if (isWall[i2])
                    {
                        meshZone.BoundThreads[i2].ThreadIndex.FaceIDs.GetSeg(out int i3, out int endp1, taskIndex);
                        for (; i3 < endp1; i3++)
                        {
                            isWallAdj[Faces[i3].OSideCell] = true;
                        }
                    }
                }
            }
        }
    }
}
//for (int i2 = 0; i2 < zone.BoundThreads.Count; i2++)
//{
//    if (!isWall[i2])
//    {
//        zone.BoundThreads[i2].ThreadIndex.FaceIDs.GetSeg(out int i3, out int endp1, taskIndex);
//        for (; i3 < endp1; i3++)
//        {
//            isWallAdj[faces[i3].OSideCell] = false;
//        }
//    }
//}
//TasksControl.Sync(taskIndex);

//public void remove_e0_e_bound(int threadIndex)
//{
//    e0_bound.Remove(threadIndex);
//    e_bound.Remove(threadIndex);
//}
//protected bool removeBoundarySetting<T>(List<T> boundaries, int threadIndex) where T : BoundaryBase_Head
//{
//    for (int i1 = 0; i1 < boundaries.Count; i1++)
//    {
//        if (boundaries[i1].threadIndex == threadIndex)
//        {
//            boundaries.RemoveAt(i1);
//            return true;
//        }
//    }
//    return false;
//}